package marking.liu.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import lombok.extern.slf4j.Slf4j;
import marking.liu.constant.LoginConstant;
import marking.liu.constant.ResponseCodeConstant;
import marking.liu.exception.LoginException;
import marking.liu.mapper.SysUserMapper;
import marking.liu.pojo.dto.LoginDto;
import marking.liu.pojo.entity.SysUser;
import marking.liu.pojo.vo.LoginVo;
import marking.liu.service.UserService;
import marking.liu.utils.IdWorkerUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 定义用户服务实现
 */
@Service("UserService")
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private HttpServletResponse httpServletResponse;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IdWorkerUtil idWorkerUtil;

    /**
     * 根据用户名获取用户信息
     *
     * @param userName
     * @return
     */
    public SysUser findByUserName(String userName) {
        return sysUserMapper.findUserInfoByUsername(userName);
    }

    /**
     * 用户登录
     *
     * @param loginDto
     * @return
     */
    public LoginVo login(LoginDto loginDto) {

        String captchCode = (String) redisTemplate.opsForValue().get(loginDto.getSessionId());
//        判断sessionId是否过期(生命周期为1分钟)
        if (StringUtils.isBlank(captchCode)) {
            throw new LoginException(LoginConstant.CAPTCHCODETIMEOUT);
        }
//        判断输入的验证码是否正确
        if (!loginDto.getCode().equals(captchCode)) {
            throw new LoginException(LoginConstant.CAPTCHCODEERROR);
        }
//        判断用户名或者密码是否为空输入
        if (loginDto == null || StringUtils.isBlank(loginDto.getUsername()) || StringUtils.isBlank(loginDto.getPassword())) {
            httpServletResponse.setStatus(ResponseCodeConstant.BADREQUEST.getCode());
            throw new LoginException(LoginConstant.LOGINFAIL);
        }
//        根据用户名查询用户信息
        SysUser user = sysUserMapper.findUserInfoByUsername(loginDto.getUsername());
//        判断用户是否存在，存在则密码校验比对
        if (user == null) {
            throw new LoginException(LoginConstant.USERNAMEEXIST);
        }
        if (!passwordEncoder.matches(loginDto.getPassword(), user.getPassword())) {
            throw new LoginException(LoginConstant.PASSWORDFAIL);
        }
        LoginVo loginVo = new LoginVo();
        BeanUtils.copyProperties(user, loginVo);
        return loginVo;
    }

    /**
     * 生成验证码
     *
     * @return
     */
    public Map getCaptchaCode() {
//        参数分别是宽、高、验证码长度、干扰线数量
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(250, 40, 4, 5);
//        设置背景颜色清灰
        captcha.setBackground(Color.lightGray);
//        获取图片中的验证码，默认生成的校验码包含文字和数字，长度为4
        String checkCode = captcha.getCode();
        log.info("生成校验码:{}", checkCode);
//        生成sessionId
        String sessionId = String.valueOf(idWorkerUtil.nextId());
//        将sessionId和校验码保存在redis下，并设置缓存中数据存活时间一分钟
        redisTemplate.opsForValue().set(sessionId, checkCode, 1, TimeUnit.MINUTES);
//        组装响应数据
        HashMap<String, String> captchaCode = new HashMap<>();
        captchaCode.put("sessionId", sessionId);
        captchaCode.put("imageData", captcha.getImageBase64());//获取base64格式的图片数据
        return captchaCode;
    }
}
